import mongoose from 'mongoose';
import { TeamDAO } from '../dao/TeamDAO';
import { DepartmentDAO } from '../dao/DepartmentDAO';
import { GroupDAO } from '../dao/GroupDAO';
import { OrganizationPermissionDAO } from '../dao/OrganizationPermissionDAO';
import { PermissionDAO } from '../dao/PermissionDAO';
import { ITeam } from '../models/team';
import { IDepartment } from '../models/department';
import { IGroup } from '../models/group';
import { IOrganizationPermission } from '../models/organizationPermission';
import { IPermission } from '../models/permission';

export interface CreateTeamData {
  name: string;
  description?: string;
  leaderId: string | mongoose.Types.ObjectId;
}

export interface CreateDepartmentData {
  name: string;
  description?: string;
  teamId: string | mongoose.Types.ObjectId;
  managerId: string | mongoose.Types.ObjectId;
}

export interface CreateGroupData {
  name: string;
  description?: string;
  departmentId: string | mongoose.Types.ObjectId;
  leaderId: string | mongoose.Types.ObjectId;
}

export interface UpdateTeamData {
  name?: string;
  description?: string;
  leaderId?: string | mongoose.Types.ObjectId;
  status?: number;
}

export interface UpdateDepartmentData {
  name?: string;
  description?: string;
  managerId?: string | mongoose.Types.ObjectId;
  status?: number;
}

export interface UpdateGroupData {
  name?: string;
  description?: string;
  leaderId?: string | mongoose.Types.ObjectId;
  status?: number;
}

export interface OrganizationTreeNode {
  _id: mongoose.Types.ObjectId;
  name: string;
  description?: string;
  type: 'team' | 'department' | 'group';
  children?: OrganizationTreeNode[];
  departments?: OrganizationTreeNode[];
  groups?: OrganizationTreeNode[];
  leaderId?: mongoose.Types.ObjectId;
  managerId?: mongoose.Types.ObjectId;
  status: number;
  createdAt: Date;
  updatedAt: Date;
}

export interface InheritPermissionsResult {
  inheritedCount: number;
  skippedCount: number;
  errors: string[];
}

export interface AssignPermissionsResult {
  assignedCount: number;
  skippedCount: number;
  errors: string[];
}

export interface RevokePermissionsResult {
  revokedCount: number;
  errors: string[];
}

export class OrganizationService {
  private teamDAO: TeamDAO;
  private departmentDAO: DepartmentDAO;
  private groupDAO: GroupDAO;
  private organizationPermissionDAO: OrganizationPermissionDAO;
  private permissionDAO: PermissionDAO;

  constructor() {
    this.teamDAO = new TeamDAO();
    this.departmentDAO = new DepartmentDAO();
    this.groupDAO = new GroupDAO();
    this.organizationPermissionDAO = new OrganizationPermissionDAO();
    this.permissionDAO = new PermissionDAO();
  }

  /**
   * 创建团队
   */
  async createTeam(teamData: CreateTeamData): Promise<ITeam> {
    // 验证输入数据
    if (!teamData.name || teamData.name.trim() === '') {
      throw new Error('团队名称不能为空');
    }

    if (!mongoose.Types.ObjectId.isValid(teamData.leaderId)) {
      throw new Error('无效的领导者ID');
    }

    try {
      const createData = {
        ...teamData,
        leaderId: new mongoose.Types.ObjectId(teamData.leaderId)
      };
      return await this.teamDAO.create(createData);
    } catch (error: any) {
      throw new Error(`创建团队失败: ${error.message}`);
    }
  }

  /**
   * 创建部门
   */
  async createDepartment(departmentData: CreateDepartmentData): Promise<IDepartment> {
    // 验证输入数据
    if (!departmentData.name || departmentData.name.trim() === '') {
      throw new Error('部门名称不能为空');
    }

    if (!mongoose.Types.ObjectId.isValid(departmentData.teamId)) {
      throw new Error('无效的团队ID');
    }

    if (!mongoose.Types.ObjectId.isValid(departmentData.managerId)) {
      throw new Error('无效的管理者ID');
    }

    // 验证团队是否存在
    const team = await this.teamDAO.findById(departmentData.teamId);
    if (!team) {
      throw new Error('指定的团队不存在');
    }

    try {
      const createData = {
        ...departmentData,
        teamId: new mongoose.Types.ObjectId(departmentData.teamId),
        managerId: new mongoose.Types.ObjectId(departmentData.managerId)
      };
      return await this.departmentDAO.create(createData);
    } catch (error: any) {
      throw new Error(`创建部门失败: ${error.message}`);
    }
  }

  /**
   * 创建小组
   */
  async createGroup(groupData: CreateGroupData): Promise<IGroup> {
    // 验证输入数据
    if (!groupData.name || groupData.name.trim() === '') {
      throw new Error('小组名称不能为空');
    }

    if (!mongoose.Types.ObjectId.isValid(groupData.departmentId)) {
      throw new Error('无效的部门ID');
    }

    if (!mongoose.Types.ObjectId.isValid(groupData.leaderId)) {
      throw new Error('无效的领导者ID');
    }

    // 验证部门是否存在
    const department = await this.departmentDAO.findById(groupData.departmentId);
    if (!department) {
      throw new Error('指定的部门不存在');
    }

    try {
      const createData = {
        ...groupData,
        departmentId: new mongoose.Types.ObjectId(groupData.departmentId),
        leaderId: new mongoose.Types.ObjectId(groupData.leaderId)
      };
      return await this.groupDAO.create(createData);
    } catch (error: any) {
      throw new Error(`创建小组失败: ${error.message}`);
    }
  }

  /**
   * 获取组织架构树
   */
  async getOrganizationTree(): Promise<{ teams: OrganizationTreeNode[] }> {
    try {
      // 获取所有团队
      const teams = await this.teamDAO.findAll();
      
      // 获取所有部门
      const departmentResult = await this.departmentDAO.findAll();
      const departments = departmentResult.departments;
      
      // 获取所有小组
      const groupResult = await this.groupDAO.findAll();
      const groups = groupResult.groups;

      // 构建组织架构树
      const organizationTree = teams.map(team => {
        const teamNode: OrganizationTreeNode = {
          _id: team._id as mongoose.Types.ObjectId,
          name: team.name,
          description: team.description,
          type: 'team',
          leaderId: team.leaderId as mongoose.Types.ObjectId,
          status: team.status,
          createdAt: team.createdAt,
          updatedAt: team.updatedAt,
          departments: []
        };

        // 添加该团队下的部门
        const teamDepartments = departments.filter(dept => 
          dept.teamId?.toString() === team._id?.toString()
        );

        teamNode.departments = teamDepartments.map(dept => {
          const deptNode: OrganizationTreeNode = {
            _id: dept._id as mongoose.Types.ObjectId,
            name: dept.name,
            description: dept.description,
            type: 'department',
            managerId: dept.managerId as mongoose.Types.ObjectId,
            status: dept.status,
            createdAt: dept.createdAt,
            updatedAt: dept.updatedAt,
            groups: []
          };

          // 添加该部门下的小组
          const deptGroups = groups.filter(group => 
            group.departmentId?.toString() === dept._id?.toString()
          );

          deptNode.groups = deptGroups.map(group => ({
            _id: group._id as mongoose.Types.ObjectId,
            name: group.name,
            description: group.description,
            type: 'group' as const,
            leaderId: group.leaderId as mongoose.Types.ObjectId,
            status: group.status,
            createdAt: group.createdAt || new Date(),
            updatedAt: group.updatedAt || new Date()
          }));

          return deptNode;
        });

        return teamNode;
      });

      return { teams: organizationTree };
    } catch (error: any) {
      throw new Error(`获取组织架构树失败: ${error.message}`);
    }
  }

  /**
   * 继承上级权限
   */
  async inheritPermissions(
    parentOrgId: string | mongoose.Types.ObjectId,
    parentOrgType: 'team' | 'department' | 'group',
    childOrgId: string | mongoose.Types.ObjectId,
    childOrgType: 'team' | 'department' | 'group',
    systemId: string | mongoose.Types.ObjectId,
    assignedBy: string | mongoose.Types.ObjectId
  ): Promise<InheritPermissionsResult> {
    const result: InheritPermissionsResult = {
      inheritedCount: 0,
      skippedCount: 0,
      errors: []
    };

    try {
      // 获取上级组织的权限
      const parentPermissions = await this.organizationPermissionDAO.findByOrganizationId(
        parentOrgId,
        parentOrgType,
        systemId
      );

      for (const parentPermission of parentPermissions) {
        try {
          // 检查子组织是否已有该权限
          const hasPermission = await this.organizationPermissionDAO.hasPermission(
            childOrgId,
            childOrgType,
            parentPermission.permissionId,
            systemId
          );

          if (hasPermission) {
            result.skippedCount++;
            continue;
          }

          // 创建继承的权限
          await this.organizationPermissionDAO.create({
            organizationId: new mongoose.Types.ObjectId(childOrgId),
            organizationType: childOrgType,
            permissionId: new mongoose.Types.ObjectId(parentPermission.permissionId),
            systemId: new mongoose.Types.ObjectId(systemId),
            assignedBy: new mongoose.Types.ObjectId(assignedBy),
            assignedAt: new Date(),
            status: 1,
            inherited: true,
            source: 'inherited'
          });

          result.inheritedCount++;
        } catch (error: any) {
          result.errors.push(`继承权限 ${parentPermission.permissionId} 失败: ${error.message}`);
        }
      }

      return result;
    } catch (error: any) {
      throw new Error(`权限继承失败: ${error.message}`);
    }
  }

  /**
   * 分配组织权限
   */
  async assignOrganizationPermissions(
    organizationId: string | mongoose.Types.ObjectId,
    organizationType: 'team' | 'department' | 'group',
    permissionIds: (string | mongoose.Types.ObjectId)[],
    systemId: string | mongoose.Types.ObjectId,
    assignedBy: string | mongoose.Types.ObjectId
  ): Promise<AssignPermissionsResult> {
    const result: AssignPermissionsResult = {
      assignedCount: 0,
      skippedCount: 0,
      errors: []
    };

    if (!permissionIds || permissionIds.length === 0) {
      throw new Error('权限ID列表不能为空');
    }

    for (const permissionId of permissionIds) {
      // 验证权限是否存在
      const permission = await this.permissionDAO.findById(permissionId);
      if (!permission) {
        throw new Error('权限不存在');
      }

      try {
        // 检查是否已分配该权限
        const hasPermission = await this.organizationPermissionDAO.hasPermission(
          organizationId,
          organizationType,
          permissionId,
          systemId
        );

        if (hasPermission) {
          result.skippedCount++;
          continue;
        }

        // 创建权限分配
        await this.organizationPermissionDAO.create({
          organizationId: new mongoose.Types.ObjectId(organizationId),
          organizationType: organizationType,
          permissionId: new mongoose.Types.ObjectId(permissionId),
          systemId: new mongoose.Types.ObjectId(systemId),
          assignedBy: new mongoose.Types.ObjectId(assignedBy),
          assignedAt: new Date(),
          status: 1,
          inherited: false,
          source: 'direct'
        });

        result.assignedCount++;
      } catch (error: any) {
        result.errors.push(`分配权限 ${permissionId} 失败: ${error.message}`);
      }
    }

    return result;
  }

  /**
   * 获取组织权限
   */
  async getOrganizationPermissions(
    organizationId: string | mongoose.Types.ObjectId,
    organizationType: 'team' | 'department' | 'group',
    systemId: string | mongoose.Types.ObjectId,
    includeInherited: boolean = true
  ): Promise<IOrganizationPermission[]> {
    if (!mongoose.Types.ObjectId.isValid(organizationId)) {
      throw new Error('无效的组织ID');
    }

    if (!mongoose.Types.ObjectId.isValid(systemId)) {
      throw new Error('无效的系统ID');
    }

    try {
      return await this.organizationPermissionDAO.getOrganizationPermissionsInSystem(
        organizationId,
        organizationType,
        systemId,
        includeInherited
      );
    } catch (error: any) {
      throw new Error(`获取组织权限失败: ${error.message}`);
    }
  }

  /**
   * 撤销组织权限
   */
  async revokeOrganizationPermissions(
    organizationId: string | mongoose.Types.ObjectId,
    organizationType: 'team' | 'department' | 'group',
    permissionIds: (string | mongoose.Types.ObjectId)[],
    systemId: string | mongoose.Types.ObjectId
  ): Promise<RevokePermissionsResult> {
    const result: RevokePermissionsResult = {
      revokedCount: 0,
      errors: []
    };

    if (!permissionIds || permissionIds.length === 0) {
      throw new Error('权限ID列表不能为空');
    }

    for (const permissionId of permissionIds) {
      try {
        const deleted = await this.organizationPermissionDAO.delete(new mongoose.Types.ObjectId(permissionId));

        if (deleted) {
          result.revokedCount++;
        }
      } catch (error: any) {
        result.errors.push(`撤销权限 ${permissionId} 失败: ${error.message}`);
      }
    }

    return result;
  }

  /**
   * 更新团队信息
   */
  async updateTeam(
    teamId: string | mongoose.Types.ObjectId,
    updateData: UpdateTeamData
  ): Promise<ITeam> {
    if (!mongoose.Types.ObjectId.isValid(teamId)) {
      throw new Error('无效的团队ID');
    }

    if (updateData.leaderId && !mongoose.Types.ObjectId.isValid(updateData.leaderId)) {
      throw new Error('无效的领导者ID');
    }

    try {
      const updateDataWithObjectId: any = {
        ...updateData
      };
      if (updateData.leaderId) {
        updateDataWithObjectId.leaderId = new mongoose.Types.ObjectId(updateData.leaderId);
      }
      const updatedTeam = await this.teamDAO.update(teamId, updateDataWithObjectId);
      if (!updatedTeam) {
        throw new Error('团队不存在');
      }
      return updatedTeam;
    } catch (error: any) {
      throw new Error(`更新团队失败: ${error.message}`);
    }
  }

  /**
   * 更新部门信息
   */
  async updateDepartment(
    departmentId: string | mongoose.Types.ObjectId,
    updateData: UpdateDepartmentData
  ): Promise<IDepartment> {
    if (!mongoose.Types.ObjectId.isValid(departmentId)) {
      throw new Error('无效的部门ID');
    }

    if (updateData.managerId && !mongoose.Types.ObjectId.isValid(updateData.managerId)) {
      throw new Error('无效的管理者ID');
    }

    try {
      const updateDataWithObjectId: any = {
        ...updateData
      };
      if (updateData.managerId) {
        updateDataWithObjectId.managerId = new mongoose.Types.ObjectId(updateData.managerId);
      }
      const updatedDepartment = await this.departmentDAO.update(departmentId, updateDataWithObjectId);
      if (!updatedDepartment) {
        throw new Error('部门不存在');
      }
      return updatedDepartment;
    } catch (error: any) {
      throw new Error(`更新部门失败: ${error.message}`);
    }
  }

  /**
   * 更新小组信息
   */
  async updateGroup(
    groupId: string | mongoose.Types.ObjectId,
    updateData: UpdateGroupData
  ): Promise<IGroup> {
    if (!mongoose.Types.ObjectId.isValid(groupId)) {
      throw new Error('无效的小组ID');
    }

    if (updateData.leaderId && !mongoose.Types.ObjectId.isValid(updateData.leaderId)) {
      throw new Error('无效的领导者ID');
    }

    try {
      const updateDataWithObjectId: any = {
        ...updateData
      };
      if (updateData.leaderId) {
        updateDataWithObjectId.leaderId = new mongoose.Types.ObjectId(updateData.leaderId);
      }
      const updatedGroup = await this.groupDAO.update(groupId, updateDataWithObjectId);
      if (!updatedGroup) {
        throw new Error('小组不存在');
      }
      return updatedGroup;
    } catch (error: any) {
      throw new Error(`更新小组失败: ${error.message}`);
    }
  }

  /**
   * 删除团队
   */
  async deleteTeam(teamId: string | mongoose.Types.ObjectId): Promise<boolean> {
    if (!mongoose.Types.ObjectId.isValid(teamId)) {
      throw new Error('无效的团队ID');
    }

    try {
      // 检查团队下是否有部门
      const departments = await this.departmentDAO.findByTeam(teamId);
      if (departments && departments.length > 0) {
        throw new Error('无法删除团队，该团队下还有部门');
      }

      return await this.teamDAO.delete(teamId);
    } catch (error: any) {
      throw new Error(`删除团队失败: ${error.message}`);
    }
  }

  /**
   * 删除部门
   */
  async deleteDepartment(departmentId: string | mongoose.Types.ObjectId): Promise<boolean> {
    if (!mongoose.Types.ObjectId.isValid(departmentId)) {
      throw new Error('无效的部门ID');
    }

    try {
      // 检查部门下是否有小组
      const groups = await this.groupDAO.findByDepartment(departmentId);
      if (groups && groups.length > 0) {
        throw new Error('无法删除部门，该部门下还有小组');
      }

      return await this.departmentDAO.delete(departmentId);
    } catch (error: any) {
      throw new Error(`删除部门失败: ${error.message}`);
    }
  }

  /**
   * 删除小组
   */
  async deleteGroup(groupId: string | mongoose.Types.ObjectId): Promise<boolean> {
    if (!mongoose.Types.ObjectId.isValid(groupId)) {
      throw new Error('无效的小组ID');
    }

    try {
      return await this.groupDAO.delete(groupId);
    } catch (error: any) {
      throw new Error(`删除小组失败: ${error.message}`);
    }
  }
}